﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using ATPlatforms.RabbitSkin.Serializers;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
using RabbitMQ.Client.MessagePatterns;

namespace ATPlatforms.RabbitSkin
{
    public class FanoutConsumer<T> : BaseProducerConsumer<T>
    {
        public delegate void onReceiveMessage(T message);

        public event onReceiveMessage onMessageReceived;

        public FanoutConsumer()
            : base()
        {
            MyExchangeType = ExchangeType.Fanout;
        }

        public override bool OnStart(string routingKey)
        {
            string queue = Model.QueueDeclare();
            Model.QueueBind(queue, Exchange, routingKey, false, null);
            ConsumeDelegate c = new ConsumeDelegate(Consume);
            c.BeginInvoke(queue, null, null);
            return true;
        }

        //non-blocking 
        private delegate void ConsumeDelegate(string queue);

        private void Consume(string queue)
        {
            var subscription = new Subscription(Model, queue, false);
            Running = true;
            while (Running)
            {
                BasicDeliverEventArgs basicDeliveryEventArgs = subscription.Next();
                T messageContent = MessageSerializer.DeSerializeMessage(basicDeliveryEventArgs.Body);

                if (onMessageReceived != null)
                    onMessageReceived.BeginInvoke(messageContent, null, null);
             
                subscription.Ack(basicDeliveryEventArgs);
            }
        }


    }

}
